package com.cloud.system.api.service.impl;

import java.util.*;

import com.cloud.system.api.bean.RecCheckUnitCriteriaBean;
import com.cloud.system.api.bean.RecPunishSuperviseItemCriteriaBean;
import com.cloud.system.api.bean.SuperviseBean;
import com.cloud.system.api.entity.DicRegion;
import com.cloud.system.api.entity.UnitInfo;
import com.cloud.system.api.mapper.*;
import com.cloud.system.common.utils.SessionHelper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.cloud.system.api.entity.SysConfig;
import com.cloud.system.api.entity.UnitDomain;
import com.cloud.system.api.service.SystemCacheService;
import com.cloud.system.common.result.SelectItem;

import tk.mybatis.mapper.entity.Example;

@Service
@Transactional
@CacheConfig(cacheNames = "system/cache")
public class SystemCacheServiceImpl implements SystemCacheService {

	@Autowired
	private SysDictItemMapper sysDictItemMapper;

	@Autowired
	private SysConfigMapper sysConfigMapper;
	
	@Autowired
	private CacheManager cacheManager;

	@Autowired
	private UnitDomainMapper unitDomainMapper;

	@Autowired
	private UnitInfoMapper unitInfoMapper;

	@Autowired
	private DicRegionMapper dicRegionMapper;

	@Autowired
	private HumanInfoMapper humanInfoMapper;

	@Autowired
	private UnitSuperviseMapper unitSuperviseMapper;

	@Override
//	@Cacheable
	public List<SelectItem> loadSelectItem(String itemKey) {
		return sysDictItemMapper.loadSelectItem(itemKey);
	}

	@Override
	@Cacheable
	public Map<String, String> listDictItemMap(String itemKey) {
		List<SelectItem> items = this.loadSelectItem(itemKey);
		Map<String, String> map = new HashMap<String, String>();
		for (SelectItem item : items) {
			map.put(item.getLabel(), item.getValue() + "");
		}
		return map;
	}

	@Override
	public void evitDictCache(String itemKey) {
		cacheManager.getCache("system/cache").evict(
				"com.cloud.system.api.service.impl.SystemCacheServiceImpl_loadSelectItem_" + itemKey);
		cacheManager.getCache("system/cache").evict(
				"com.cloud.system.api.service.impl.SystemCacheServiceImpl_listDictItemMap_"+ itemKey);
	}

	@Override
	@Cacheable
	public String loadSysConfigItem(String configKey) {
		SysConfig config = new SysConfig();
		config.setConfigKey(configKey);
		SysConfig cfg =  sysConfigMapper.selectByPrimaryKey(config);
		if(null == cfg || StringUtils.isEmpty(cfg.getConfigValue())){
			return null;
		}
		return cfg.getConfigValue();
	}

	@Override
	@Cacheable
	public List<SysConfig> loadAllSysConfigItem() {
		List<SysConfig> sysConfigs = sysConfigMapper.selectAll();
		return sysConfigs;
	}

	@Override
	public void evitSysConfigItemCache(String configName) {
		cacheManager.getCache("system/cache").evict(
				"com.cloud.system.api.service.impl.SystemCacheServiceImpl_evitSysConfigItemCache_" + configName);

	}
	
	@Override
	@Cacheable
	public List<SelectItem> loadUnitDomains(long unitId) {
		List<UnitDomain> domains = null;
		UnitInfo unit = unitInfoMapper
				.selectByPrimaryKey(unitId);
		 // 区域管理员  和超级管理员 领域不过滤
		if("0".equals(unit.getUnitTypeId())){
			return this.loadSelectItem("UNIT_DOMAIN");
		}
		Example example = new Example(UnitDomain.class);
		Example.Criteria criteria = example.createCriteria();
		criteria.andEqualTo("unitId", unitId);
		domains = unitDomainMapper.selectByExample(example);
		List<SelectItem> items = new ArrayList<SelectItem>();
		for(UnitDomain domain : domains){
			items.add(new SelectItem(domain.getDomainTypeName(), domain.getDomainTypeId()));
		}
		return items;
	}

	@Override
	@Cacheable
	public List<UnitInfo> loadUnitAreas() {
		Example example = new Example(UnitInfo.class);
		Example.Criteria criteria = example.createCriteria();
		criteria.andEqualTo("deleteFlag", 0);
		criteria.andEqualTo("unitTypeId", 0);
		List<UnitInfo> unitInfos = unitInfoMapper.selectByExample(example);
		return unitInfos;
	}

	@Override
	public void evitUnitDomainsCache(long unitId) {
		cacheManager.getCache("system/cache").evict(
				"com.cloud.system.api.service.impl.SystemCacheServiceImpl_loadUnitDomains_" + unitId);
	}

	@Override
	public List<SelectItem> loadAddressItems() {
		List<SelectItem> selectItems = new ArrayList<>();
		List<SelectItem> items = new ArrayList<>();//下一级
		List<SelectItem> list = dicRegionMapper.selectAllAddress();
		for (SelectItem selectItem: list) {
			if (selectItem.getLevel() == 4) {
				selectItem.setLeaf(true);
				items.add(selectItem);
			} else {
				selectItems.add(selectItem);
			}
		}
		list.clear();
		list = traversalAddress(selectItems,items,3);
		return list;
	}

	private List<SelectItem> traversalAddress(List<SelectItem> selectItems, List<SelectItem> items, int level) {
		List<SelectItem> select = new ArrayList<>();//下级
		List<SelectItem> list = new ArrayList<>();//上级
		if (level != 1) {
			for (SelectItem selectItem : selectItems) {//上级遍历
				if (selectItem.getLevel() == level) {
					List<SelectItem> selectItemList = new ArrayList<>();
					for (SelectItem item : items) {//下级遍历
						if (item.getSeniorId().equals(selectItem.getValue())) {//当属于上级时
							selectItemList.add(item);//存放在空list中
						}
					}
					selectItem.setChildren(selectItemList);//保存当前上级地址的所有下级地址
					if (selectItemList.size() == 0) {
						selectItem.setLeaf(true);
					}
					select.add(selectItem);//保存下级
				} else {
					list.add(selectItem);//保存上级
				}
			}
		} else {
			return items;
		}
		return traversalAddress(list, select, level - 1);
	}

	@Override
	public List<SelectItem> loadHuman(Long unitId){
		List<SelectItem> list = humanInfoMapper.getHumans(unitId);
		return list;
	}

	@Override
	public List<SelectItem> loadUnitDomainsByUnitId(long unitId) {
		List<UnitDomain> domains = null;
		Example example = new Example(UnitDomain.class);
		Example.Criteria criteria = example.createCriteria();
		criteria.andEqualTo("unitId", unitId);
		domains = unitDomainMapper.selectByExample(example);
		List<SelectItem> items = new ArrayList<SelectItem>();
		for(UnitDomain domain : domains){
			items.add(new SelectItem(domain.getDomainTypeName(), domain.getDomainTypeId()));
		}
		return items;
	}

	@Override
	public PageInfo<SuperviseBean> searchCheckItem(RecCheckUnitCriteriaBean recCheckUnitCriteriaBean) {
		PageInfo<SuperviseBean> page = new PageInfo<>();
		UnitInfo info = unitInfoMapper.selectByPrimaryKey(recCheckUnitCriteriaBean.getUnitId());
        if (null != info.getSubjectId() && info.getSubjectId() > 0)  {
			info = unitInfoMapper.selectByPrimaryKey(info.getSubjectId());
			if (StringUtils.isNotEmpty(info.getSocialCreditCode())) {
				List<String> supCode = unitSuperviseMapper.getSupCodeBySocialCreditCode(info.getSocialCreditCode());
				if (supCode.size() > 0) {
					recCheckUnitCriteriaBean.setSupCode(supCode);
					page = PageHelper.startPage(recCheckUnitCriteriaBean.getPageNum(), recCheckUnitCriteriaBean.getPageSize())
							.doSelectPageInfo(() -> {
								unitSuperviseMapper.searchCheckItem(recCheckUnitCriteriaBean);
							});
				}
			}
		}
		return page;
	}

	@Override
	public PageInfo<SuperviseBean> searchSuperviseItem(RecPunishSuperviseItemCriteriaBean recPunishSuperviseItemCriteriaBean) {
		PageInfo<SuperviseBean> page = new PageInfo<>();
		UnitInfo info = unitInfoMapper.selectByPrimaryKey(recPunishSuperviseItemCriteriaBean.getUnitId());
        if (null != info.getSubjectId() && info.getSubjectId() > 0) {
			info = unitInfoMapper.selectByPrimaryKey(info.getSubjectId());
			if (StringUtils.isNotEmpty(info.getSocialCreditCode())) {
				List<String> supCode = unitSuperviseMapper.getSupCodeBySocialCreditCode(info.getSocialCreditCode());
				if (supCode.size() > 0) {
					recPunishSuperviseItemCriteriaBean.setSupCode(supCode);
					page = PageHelper.startPage(recPunishSuperviseItemCriteriaBean.getPageNum(), recPunishSuperviseItemCriteriaBean.getPageSize())
							.doSelectPageInfo(() -> {
								unitSuperviseMapper.searchSuperviseItem(recPunishSuperviseItemCriteriaBean);
							});
				}
			}
		}
		return page;
	}

	@Override
	public List<SelectItem> findSubjectDomain(long unitId) {
		List<UnitDomain> domains;
		UnitInfo unit = unitInfoMapper.selectByPrimaryKey(unitId);
		if (unit.getUnitTypeId().equals("0") || unit.getUnitTypeId().equals("2")){
			return loadUnitDomains(unitId);
		}
		//查询所在执法主体下的领域
		UnitInfo subjectInfo = unitInfoMapper.selectByPrimaryKey(unit.getSubjectId());
		Example example = new Example(UnitDomain.class);
		Example.Criteria criteria = example.createCriteria();
		criteria.andEqualTo("unitId", subjectInfo.getUnitId());
		domains = unitDomainMapper.selectByExample(example);
		List<SelectItem> items = new ArrayList<SelectItem>();
		for(UnitDomain domain : domains){
			items.add(new SelectItem(domain.getDomainTypeName(), domain.getDomainTypeId()));
		}
		return items;
	}
}
